package com.shujia

/**
 * 在Scala的类定义中 由{}括起来的即是构造方法
 */
class Demo02StudentScala(id: Int, name: String, age: Int, gender: String, clazz: String) {
  // 定义属性 在Scala当中定义变量（属性）时需要赋值 --> 定义即赋值
  // 约定俗成 在Scala中定义属性时一般以下划线开头进行命名 否则会和构造方法中的命名冲突
  val _id: Int = id
  // Scala中也可以使用访问控制符修饰变量以及方法
  private val _name: String = name
  val _age: Int = age
  val _gender: String = gender
  val _clazz: String = clazz
  // 如果需要待会给属性进行赋值 可以给它先赋一个下划线 表示稍后进行赋值
  // 但是如果使用了下划线_ 则Scala编译器无法自动完成类型的推断 需要手动指定类型
  var _phoneNum: String = _

  // 如果需要重载构造方法 可以通过this实现
  def this(id: Int, name: String, age: Int, gender: String, clazz: String, phoneNum: String) {
    // 第一行代码必须调用默认的构造方法 通过this可以直接调用 注意在这里不会形成递归
    this(id, name, age, gender, clazz)
    println("重载了构造方法")
    _phoneNum = phoneNum
  }

  // 对于用private修饰的属性 可以定义一个get方法进行获取
  def getName(): String = {
    this._name
  }


  // 定义函数（方法）
  def printInfo(): Unit = {
    println("打印学生的基本信息")
  }

}

/**
 * 如果object和class同名
 * 其次在object中实现了apply方法
 * 那么就可以将object成为class的伴生对象
 * 在创建class的对象时 可以不使用new关键字
 */
object Demo02StudentScala {
  def main(args: Array[String]): Unit = {
    val stu01 = new Demo02StudentScala(1500100001, "施笑槐", 22, "女", "文科六班")
    // 通过类的对象 可以获取定义的属性、方法
    println(stu01._id)
    println(stu01.getName())
    println(stu01._phoneNum)
    stu01.printInfo()

    // 使用重载的构造方法
    val stu02 = new Demo02StudentScala(1500100008, "符半双", 22, "女", "理科六班", "18888888888")
    println(stu02._id)
    println(stu02.getName())
    println(stu02._phoneNum)
    stu02.printInfo()

    // 不使用new关键字创建对象，会默认调用同名的object中的apply方法
    val stu03: Demo02StudentScala = Demo02StudentScala(1500100008, "符半双", 22, "女", "理科六班")
    val stu04: Demo02StudentScala = Demo02StudentScala(1500100008, "符半双", 22, "女", "理科六班", "18888888888")

  }

  // apply方法
  def apply(id: Int, name: String, age: Int, gender: String, clazz: String): Demo02StudentScala = {
    return new Demo02StudentScala(id, name, age, gender, clazz)
  }

  // apply方法也能进行重载
  def apply(id: Int, name: String, age: Int, gender: String, clazz: String, phoneNum: String): Demo02StudentScala = {
    return new Demo02StudentScala(id, name, age, gender, clazz, phoneNum)
  }
}
